/*******************************************************************************
 *                                    ZLG
 *                         ----------------------------
 *                         innovating embedded platform
 *
 * Copyright (c) 2001-present Guangzhou ZHIYUAN Electronics Co., Ltd.
 * All rights reserved.
 *
 * Contact information:
 * web site:    https://www.zlg.cn
 *******************************************************************************/
/*******************************************************************************
 * Includes
 ******************************************************************************/
#include "core/include/hpm6e00_l1_cache.h"

/*******************************************************************************
 * Code
 ******************************************************************************/
/**
 * \brief l1 cache D-Cache 使能
 */
void l1c_dc_enable(void){
    if (!l1c_dc_is_enabled()) {
#ifdef L1C_DC_DISABLE_WRITEAROUND_ON_ENABLE
        l1c_dc_disable_writearound();
#else
        l1c_dc_enable_writearound();
#endif
        set_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_DPREF_EN_MASK | HPM_MCACHE_CTL_DC_EN_MASK);
    }
}

/**
 * \brief l1 cache D-Cache 禁能
 */
void l1c_dc_disable(void){
    if (l1c_dc_is_enabled()) {
        clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_DC_EN_MASK);
    }
}

/**
 * \brief l1 cache I-Cache 使能
 */
void l1c_ic_enable(void){
    if (!l1c_ic_is_enabled()) {
        set_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_IPREF_EN_MASK
                              | HPM_MCACHE_CTL_CCTL_SUEN_MASK
                              | HPM_MCACHE_CTL_IC_EN_MASK);
    }
}

/**
 * \brief l1 cache I-Cache 禁能
 */
void l1c_ic_disable(void){
    if (l1c_ic_is_enabled()) {
        clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_IC_EN_MASK);
    }
}

static void l1c_op(uint8_t opcode, uint32_t address, uint32_t size){
    register uint32_t next_address;
    next_address = address;
    l1c_cctl_address(next_address);
    while ((next_address < (address + size)) && (next_address >= address)) {
        l1c_cctl_cmd(opcode);
        next_address = l1c_cctl_get_address();
    }
}

/**
 * \brief l1 cache 无效化
 */
void l1c_dc_invalidate(uint32_t address, uint32_t size){
    if (((address % HPM_L1C_CACHELINE_SIZE) != 0) || \
            ((size % HPM_L1C_CACHELINE_SIZE) != 0)) {
        return;
    }
    l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_INVAL, address, size);
}


/**
 * \brief l1 cache 无效化全部 D-Cache
 */
void l1c_dc_invalidate_all(void){
    l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_INVAL_ALL);
}

/**
 * \brief l1 cache 刷新全部 D-Cache
 */
void l1c_dc_flush_all(void){
    l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_WBINVAL_ALL);
}

/**
 * \brief l1 cache D-Cache writearound 使能
 */
void l1c_dc_enable_writearound(void){
    set_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_DC_WAROUND_MASK);
}


